package com.pcj.blog.service;/**
 * @param
 * @author pcj
 * @date 2022/1/5 20:15
 * @return
 */

import com.pcj.blog.dao.CommentRepository;
import com.pcj.blog.po.Comment;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;

import javax.transaction.Transactional;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 *
 * @className CommentServiceImpl
 * @author pengcj
 * @date 2022/1/5 20:15
 */
@Service
public class CommentServiceImpl implements CommentService{
    @Autowired
    private CommentRepository commentRepository;
    @Override
    public List<Comment> listCommentByBlogId(Long id) {
        Sort sort= Sort.by(Sort.Direction.DESC,"creatTime");
        List<Comment>comments=commentRepository.findByBlogIdAndParentCommentNull(id,sort); //拿到当前博客的所有顶级评论  即parentComment=null
        return eachComment(comments);
    }

    @Transactional
    @Override
    public Comment saveComment(Comment comment) {
        Long parentCommentId=comment.getParentComment().getId();
        if(parentCommentId != -1){
            comment.setParentComment(commentRepository.getById(parentCommentId)); //拿到父级的信息 放到comment里面
        }else{
            comment.setParentComment(null); // 说明没有父级评论  直接评论博客
        }
        comment.setCreatTime(new Date());
        return commentRepository.save(comment);
    }
    /**
     * 循环每个顶级的评论节点
     * @param comments
     * @return
     */
    private List<Comment> eachComment(List<Comment> comments) {
//        System.out.println("顶级comments:"+comments);
        //复制一份comments  避免对原有的数据被破坏
        List<Comment> commentsView = new ArrayList<>();
        for (Comment comment : comments) {
            Comment c = new Comment();
            BeanUtils.copyProperties(comment,c);
            commentsView.add(c);
        }
        //合并评论的各层子代到第一级子代集合中
        combineChildren(commentsView);
        return commentsView;
    }

    /**
     *
     * @param comments root根节点，blog不为空的对象集合
     * @return
     */
    private void combineChildren(List<Comment> comments) {

        for (Comment comment : comments) {
            List<Comment> replys1 = comment.getReplyComments();   //循环拿到每条顶级评论的子级   不包括子级的子级
            for(Comment reply1 : replys1) {
                //循环迭代，找出所有子级，存放在tempReplys中
                recursively(reply1);
            }
            //  此时所有的子评论都已经放进了  tempReplys中
            //修改顶级节点的reply集合为迭代处理后的集合
            comment.setReplyComments(tempReplys);
            //清除临时存放区
            tempReplys = new ArrayList<>();
        }
    }

    //存放迭代找出的所有子代的集合
    private List<Comment> tempReplys = new ArrayList<>();
    /**
     * 找出子级的所有子级评论
     * 递归迭代，剥洋葱
     * @param comment 被迭代的对象
     * @return
     */
    private void recursively(Comment comment) {
        tempReplys.add(comment);//将第一级的子级评论存入tempReplys
        if (comment.getReplyComments().size()>0) {
            //拿到第一级子级评论的所有子级
            List<Comment> replys = comment.getReplyComments();
            for (Comment reply : replys) { //循环每一个子级  存入tempReplys
                tempReplys.add(reply);
                if (reply.getReplyComments().size()>0) { //若子级还有子级则继续迭代
                    recursively(reply);
                }
            }
        }
    }
}
